


package mapbase
{
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Endian;
	import flash.utils.IDataInput;
	
	import interfaces.IDispose;
	import mapbase.mapTerrain;
	
	public class map implements IDispose
	{
		public static const gridWidth:int = 64;
		public static const gridHeight:int = 32;
		
		public static const one_Screen_Grids_W:int = 13;
		public static const one_Screen_Grids_H:int = 19;	
		
		public static const screen9_Terrains_W:int = int((3 * one_Screen_Grids_W + 1)/2);
		public static const screen9_Terrains_H:int = int((3 * one_Screen_Grids_H + 3)/4);		
		
		public static const map_Magic:uint = 0xffaaffaa;
		public static const map_version:uint = 0x20120630;
		
		public static const map_Type_Terrain:int = 0x01;
		public static const map_Type_TileItem:int = 0x02;
		
		private var width:int;
		private var height:int;
		
		public var terrains:Vector.<mapTerrain> = new Vector.<mapTerrain>();
		public var tiles:Vector.<mapTileItemEx> = new Vector.<mapTileItemEx>();
		
		public function map():void
		{
			width = 0;
			height = 0;
		}
		
		public function getWidth():int
		{
			return width;
		}
		public function getHeight():int
		{
			return height;
		}
		
		public function getTerrain(x:int,y:int):mapTerrain
		{
			if(x < width && y < height)
			{
				return terrains[int(y/4) * int((width+1)/2) + int(x/2)];
			}
			else
			{
				return null;
			}
		}
		
		public function getTileItem(x:int,y:int):mapTileItemEx
		{
			if(x < width && y < height)
			{
				return tiles[y * width + x];
			}
			else
			{
				return null;
			}
		}
		
		public function clear():void
		{
			for(var i:int = 0; i != terrains.length;++i)
			{
				delete terrains[i];
			}
			for(i = 0; i != tiles.length;++i)
			{
				delete tiles[i];
			}
			
			width = 0;
			height = 0;
		}
		
		public function dispose():void
		{
			clear();
		}
		
		public function loadMapFrom(data:IDataInput):Boolean
		{
			data.endian = Endian.LITTLE_ENDIAN;
			var hdr:mapHead = new mapHead();
			
			hdr.magic = data.readUnsignedInt();
			hdr.version = data.readUnsignedInt();
			hdr.width = data.readUnsignedInt();
			hdr.height = data.readUnsignedInt();
			
			if(hdr.magic != map_Magic)
			{
				hdr = null;				
				return false;
			}
			if(hdr.version != map_version)
			{
				hdr = null;				
				return false;
			}
			
			width = hdr.width;
			height = hdr.height;
			
			hdr = null;
			
			while(data.bytesAvailable > 0)
			{
				var type:int = data.readInt();
				switch(type)
				{
					case map_Type_Terrain:
					{
						for(var h:int = 0; h != int((height+3)/4); ++h)
						{
							for(var w:int = 0; w != int((width+1)/2); ++w)
							{
								terrains.push(new mapTerrain(data.readInt()));
							}
						}
					}
					break;
					case map_Type_TileItem:
					{
						for(var _h:int = 0; _h != height; ++_h)
						{
							for(var _w:int = 0; _w != width; ++_w)
							{
								tiles.push(new mapTileItemEx(data.readInt()));
							}
						}
					}
					break;
					default :
					{
						return false;
					}
				}
			}
			
			return true;
		}
		
		public static function map_GridCenterToPixel(pt:Point):Point
		{
			var _t:Point = new Point();
			_t.x = int(pt.x * gridWidth + gridWidth/2);
			_t.y = int(pt.y * gridHeight + gridHeight/2);
			
			return _t;
		}		
		
		public static function map_PixelToGrid(pt:Point):Point
		{
			var _t:Point = new Point();
			_t.x = int(pt.x / gridWidth);
			_t.y = int(pt.y / gridHeight);
			
			return _t;
		}
		
		public static function map_GridCenterToPixel_Rc(rc:Rectangle):Rectangle
		{
			var _t:Rectangle = new Rectangle();
			
			var pt:Point = map_GridCenterToPixel(new Point(rc.left,rc.top));			
			_t.left = pt.x;
			_t.top = pt.y;
			_t.right = int(rc.right * gridWidth - gridWidth / 2);
			_t.bottom = int(rc.bottom * gridHeight - gridHeight / 2);
			
			return _t;
		}
		
		public static function map_PixelToGrid_Rc(rc:Rectangle):Rectangle
		{
			var _t:Rectangle = new Rectangle();
			
			var pt:Point = map_PixelToGrid(new Point(rc.left,rc.top));
			_t.left = pt.x;
			_t.top = pt.y;
			_t.right = int((rc.right + gridWidth - 1) / gridWidth);
			_t.bottom = int((rc.bottom + gridHeight - 1) / gridHeight);
			
			return _t;
		}
		
		public static function map_GirdToScreen(pt:Point):Point
		{
			var _t:Point = new Point();
			_t.x = int(pt.x / one_Screen_Grids_W);
			_t.y = int(pt.y / one_Screen_Grids_H);
			
			return _t;
		}
		public static function map_ScreenToGrid(pt:Point):Point
		{
			return new Point(pt.x * one_Screen_Grids_W,pt.y * one_Screen_Grids_H);
		}
		
		public static function map_GridToTerrain(pt:Point):Point
		{
			return new Point(int(pt.x / mapTerrain.one_Grids_W),int(pt.y / mapTerrain.one_Grids_H));
		}
		public static function map_TerrainToGrid(pt:Point):Point
		{
			return new Point(pt.x * mapTerrain.one_Grids_W,pt.y * mapTerrain.one_Grids_H);
		}
	}
}